/* Octopus PDF - A simple document viewer for Android.
   Copyright (C) 2013  Gerald Thaler

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
package de.geraldthaler.octopuspdf.view;

import static android.opengl.GLES10.GL_LINEAR;
import static android.opengl.GLES10.GL_REPEAT;
import static android.opengl.GLES10.GL_RGBA;
import static android.opengl.GLES10.GL_TEXTURE_2D;
import static android.opengl.GLES10.GL_TEXTURE_MAG_FILTER;
import static android.opengl.GLES10.GL_TEXTURE_MIN_FILTER;
import static android.opengl.GLES10.GL_TEXTURE_WRAP_S;
import static android.opengl.GLES10.GL_UNSIGNED_BYTE;
import static android.opengl.GLES10.glBindTexture;
import static android.opengl.GLES10.glDeleteTextures;
import static android.opengl.GLES10.glGenTextures;
import static android.opengl.GLES10.glTexImage2D;
import static android.opengl.GLES10.glTexParameterx;
import static de.geraldthaler.octopuspdf.Constants.TEXTURE_SIZE;
import static java.lang.Math.min;
import de.geraldthaler.octopuspdf.util.Arrays;

/**
 * @author Gerald Thaler
 */
public final class TexturePool {
    private int glGeneration;
    private int[] pool = new int[16];
    private int poolSize = 0;

    public int[] allocTextures(final int count) {
        final int[] textures = new int[count];
        final int m = min(count, poolSize);
        if (m > 0) {
            poolSize -= m;
            System.arraycopy(pool, poolSize, textures, 0, m);
        }
        final int n = count - m;
        if (n > 0) {
            glGenTextures(n, textures, m);
            for (int k = m; k < textures.length; ++k) {
                glBindTexture(GL_TEXTURE_2D, textures[k]);
                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEXTURE_SIZE, TEXTURE_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
            }
        }
        return textures;
    }

    public void clear(final int glGeneration) {
        if (glGeneration == this.glGeneration && poolSize > 0)
            glDeleteTextures(poolSize, pool, 0);
        poolSize = 0;
        this.glGeneration = glGeneration;
    }

    public void freeTextures(final int glGeneration, final int[] textures) {
        if (textures.length == 0 || glGeneration != this.glGeneration)
            return;
        if (poolSize + textures.length > pool.length)
            pool = Arrays.copyOf(pool, poolSize + textures.length);
        System.arraycopy(textures, 0, pool, poolSize, textures.length);
        poolSize += textures.length;
    }
    
    public void setGlGeneration(final int glGeneration) {
        this.glGeneration = glGeneration;
    }
}
